package runtime

import (
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
)

type ClientHeader struct {
	Id     string `json:"id"`
	Token  string `json:"token"`
	Times  string `json:"times"`
	Random string `json:"random"`

	Info map[string]interface{} `json:"info"`
}

func ParseClientHeader(bts []byte) (*ClientHeader, error) {
	if bts == nil {
		return nil, errors.New("bts is nil")
	}
	rt := &ClientHeader{}
	return rt, json.Unmarshal(bts, rt)
}

func (c *ClientHeader) Set(key string, val interface{}) {
	if c.Info == nil {
		c.Info = make(map[string]interface{})
	}
	c.Info[key] = val
}
func (c *ClientHeader) Del(key string) {
	if c.Info == nil {
		return
	}
	delete(c.Info, key)
}
func (c *ClientHeader) Bytes() []byte {
	if c == nil {
		return nil
	}
	bts, _ := json.Marshal(c)
	return bts
}
func (c *ClientHeader) Get(key string) (interface{}, bool) {
	if c.Info == nil {
		return nil, false
	}
	rt, ok := c.Info[key]
	return rt, ok
}
func (c *ClientHeader) Gets(key string) (string, bool) {
	v, ok := c.Get(key)
	if !ok {
		return "", false
	}
	switch v.(type) {
	case string:
		return v.(string), true
	}
	return fmt.Sprintf("%v", v), true
}
func (c *ClientHeader) GetInt(key string) (int64, error) {
	v, ok := c.Get(key)
	if !ok {
		return 0, errors.New("not found")
	}
	switch v.(type) {
	case int:
		return v.(int64), nil
	case string:
		return strconv.ParseInt(v.(string), 10, 64)
	case int64:
		return v.(int64), nil
	case float32:
		return int64(v.(float32)), nil
	case float64:
		return int64(v.(float64)), nil
	}
	return 0, errors.New("not found")
}
